package com.example.service.impl;

import com.example.common.UserLogMessage;
import com.example.dto.UserDTO;
import com.example.dto.UserRegisterDTO;
import com.example.feign.PermissionFeignClient;
import com.example.mapper.RolesMapper;
import com.example.mapper.UserMapper;
import com.example.pojo.*;
import com.example.service.UserService;
import com.example.util.IpUtils;
import com.example.util.JwtUtil;
import com.example.util.UserContext;
import com.example.util.UserIdGeneratorUtils;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper  userMapper;
    @Autowired
    private PermissionFeignClient permissionFeignClient;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private RolesMapper roleMapper;

    private final int MAX_RETRIES = 3;
    private final long INITIAL_RETRY_DELAY = 1000L; // 初始延迟1秒


    @Autowired
    public UserServiceImpl(UserMapper userMapper,
                           PermissionFeignClient permissionFeignClient,
                           RocketMQTemplate rocketMQTemplate) {
        this.userMapper = userMapper;
        this.permissionFeignClient = permissionFeignClient;
        this.rocketMQTemplate = rocketMQTemplate;
    }


    /**
     * 用户注册
     * @param registerDTO
     * @return
     */

    @Override
    @GlobalTransactional(name = "register", rollbackFor = Exception.class)
    public Result register(UserRegisterDTO registerDTO) {
        //判断参数
        if (registerDTO.getUsername() == null || registerDTO.getPassword() == null || registerDTO.getEmail() == null || registerDTO.getPhone() == null || registerDTO.getConfirmPassword() == null){
            log.info("请填写完整的注册信息");
            return Result.error("请填写完整的注册信息");
        }
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())){
            log.info("两次密码不一致");
            return Result.error("两次密码不一致");
        }
        //验证邮箱格式
        if (!registerDTO.getEmail().matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")){
            log.info("邮箱格式错误");
            return Result.error("邮箱格式不正确");
        }
        // 验证手机号格式
        if (!registerDTO.getPhone().matches("^1[3456789]\\d{9}$")) {
            log.info("手机号格式错误");
            return Result.error("手机号格式不正确");
        }
        Integer usernameCount = userMapper.getUsername(registerDTO.getUsername());
        Integer count = (usernameCount != null) ? usernameCount : 0;
        if(count > 0){
            log.info("用户名已存在");
            return Result.error("用户名已存在");
        }
        User user = new User();
        user.setUserId(UserIdGeneratorUtils.SnowflakeIdGenerator());
        user.setUsername(registerDTO.getUsername());
        user.setPassword(registerDTO.getPassword());
        user.setEmail(registerDTO.getEmail());
        user.setPhone(registerDTO.getPhone());
        user.setGmtCreate(LocalDateTime.now());
        //插入用户
        userMapper.insertUser(user);
        //RPC调用权限服务绑定默认角色
        log.info("开始调用权限服务绑定默认角色,userId:{}",  user.getUserId());
        permissionFeignClient.bindDefaultRole(user.getUserId());
        log.info("权限服务绑定默认角色结束");

        //发送注册日志消息到MQ
        log.info("开始发送注册日志消息到MQ");
        sendRegisterLog(user);
        log.info("发送注册日志消息结束");
        return Result.success();

    }

    //    AI生成
    //异步发送注册日志消息
    private void sendRegisterLog(User user) {
        try {
            Map<String, Object> extraData = new HashMap<>();
            extraData.put("userId", user.getUserId());
            extraData.put("username", user.getUsername());
            extraData.put("email", user.getEmail());
            extraData.put("phone", user.getPhone());

            UserLogMessage logMsg = new UserLogMessage(
                    user.getUserId(),
                    "REGISTER",
                    System.currentTimeMillis(),
                    IpUtils.getIpAddr(),
                    extraData
            );

            // 使用异步发送并添加重试机制
            rocketMQTemplate.asyncSend(
                    "USER_LOG_TOPIC",
                    MessageBuilder.withPayload(logMsg)
                            .setHeader(RocketMQHeaders.TAGS, "register")
                            .setHeader(RocketMQHeaders.KEYS, user.getUserId().toString())
                            .build(),
                    new SendCallback() {
                        private int retryCount = 0;
                        private final ScheduledExecutorService retryExecutor =
                                Executors.newSingleThreadScheduledExecutor();

                        @Override
                        public void onSuccess(SendResult sendResult) {
                            log.info("消息发送成功，Topic: {}, MsgId: {}, UserId: {}",
                                    "USER_LOG_TOPIC", sendResult.getMsgId(), user.getUserId());
                            retryExecutor.shutdown();
                        }

                        @Override
                        public void onException(Throwable e) {
                            if (retryCount < MAX_RETRIES) {
                                retryCount++;
                                long delay = INITIAL_RETRY_DELAY * (long) Math.pow(2, retryCount - 1);

                                log.warn("消息发送失败，准备第{}次重试（{}ms后），UserId: {}",
                                        retryCount, delay, user.getUserId());

                                retryExecutor.schedule(() -> {
                                    try {
                                        rocketMQTemplate.asyncSend(
                                                "USER_LOG_TOPIC",
                                                MessageBuilder.withPayload(logMsg)
                                                        .setHeader(RocketMQHeaders.TAGS, "register")
                                                        .setHeader(RocketMQHeaders.KEYS, user.getUserId().toString())
                                                        .build(),
                                                this
                                        );
                                    } catch (Exception ex) {
                                        log.error("消息重试发送异常，UserId: {}", user.getUserId(), ex);
                                    }
                                }, delay, TimeUnit.MILLISECONDS);
                            } else {
                                log.error("消息发送失败，已达最大重试次数{}，UserId: {}",
                                        MAX_RETRIES, user.getUserId(), e);
                                retryExecutor.shutdown();
                            }
                        }
                    }
            );
        } catch (Exception e) {
            log.error("消息发送异常，UserId: {}", user.getUserId(), e);
            throw new RuntimeException("消息发送异常", e);
        }
    }
    /**
     * 用户登录
     * @param user
     * @return
     */
    @Override
    public LoginInfo login(User user) {
        User u = userMapper.SelectByUsernameAndPassword ( user);
        if (u != null) {
            log.info("用户登录成功，用户名：{}", user.getUsername());

            Map<String, Object> mp = new HashMap<>();
            mp.put("userId", u.getUserId());
            mp.put("username", u.getUsername());

            String token = JwtUtil.generateJwt(mp);
            return new LoginInfo(u.getUserId(), u.getUsername(), token);
        }
        return null;
    }

    /**
     * 分页查询用户列表
     * @param userQueryParam
     * @return
     */

    @Override
    public PageResult<User> pageQuery(UserQueryParam userQueryParam, Integer roleCode) {
        log.info("得到的roleCode：{}", roleCode);
        // 1. 根据角色码获取角色ID集合
        List<Long> roleIds = getRoleIdsByRoleCode(roleCode);

        // 2. 查询符合条件的user_id
        List<Long> userIds = roleMapper.getUserIdByRoleIds(roleIds);
        if (userIds.isEmpty()){
            log.info("用户权限为使用者，返回用户自己");
            List<User> userList = userMapper.getByUserId(UserContext.getCurrentUserId());
            return new PageResult<>(1, userList);
        }

        // 3. 分页逻辑
        int total = userIds.size(); // 总记录数
        int page = userQueryParam.getPage(); // 当前页码
        int pageSize = userQueryParam.getPageSize(); // 每页大小
        int start = (page - 1) * pageSize; // 起始索引
        int end = Math.min(start + pageSize, total); // 结束索引

        // 如果总记录数为0，直接返回空结果
        if (total == 0) {
            return new PageResult<>(0, Collections.emptyList());
        }
        // 获取分页后的user_id集合
        List<Long> pagedUserIds = userIds.subList(start, end);
        // 4. 根据分页后的user_id集合查询用户信息
        List<User> userList = userMapper.queryUsersByIds(pagedUserIds, userQueryParam);
        // 发送分页查询日志消息到MQ
        sendPageQueryLog(userQueryParam, roleCode, total, userList.size());
        // 5. 返回分页结果
        return new PageResult<>(total, userList);
    }

    /**
     * 根据userId获取用户信息
     * @param userId
     * @param roleCodeId
     * @return
     */
    @Override
    public User getUserByuserId(Long userId, Integer roleCodeId) {
        // 1.记录查询开始时间
        long startTime = System.currentTimeMillis();
        // 2. 根据角色码获取角色ID集合
        List<Long> roleIds = getRoleIdsByRoleCode(roleCodeId);
        if (roleIds.isEmpty()) {
            if (Objects.equals(userId, UserContext.getCurrentUserId())) {
                log.info("用户权限为使用者，返回用户自己");
                User user = userMapper.getUserByuserId(UserContext.getCurrentUserId());
                sendUserQueryLog(userId, roleCodeId, true, "SUCCESS", startTime);
                return user;
            }
            log.info("用户权限为使用者，查询他人，返回空");
            // 发送未授权访问日志
            sendUserQueryLog(userId, roleCodeId, false, "ROLE_NOT_FOUND", System.currentTimeMillis());
            return null;
        }

        // 3. 查询符合条件的user_id
        List<Long> userIds = roleMapper.getUserIdByRoleIds(roleIds);


        try {
            if (!userIds.contains(userId)) {
                log.info("用户权限为管理员，查询权限为超级管理员的人，返回空");
                // 发送未授权访问日志
                sendUserQueryLog(userId, roleCodeId, false, "USER_NOT_IN_ROLE", startTime);
                return null;
            }
            log.info("根据userId获取用户信息，userId: {}", userId);
            // 3. 根据角色ID集合获取用户ID
            User user = userMapper.getUserByuserId(userId);
            log.info("根据userId获取用户信息成功，user: {}", user);

            // 发送成功查询日志
            if (user != null) {
                sendUserQueryLog(userId, roleCodeId, true, "SUCCESS", startTime);
            } else {
                sendUserQueryLog(userId, roleCodeId, false, "USER_NOT_FOUND", startTime);
            }

            return user;
        } catch (Exception e) {
            // 发送查询异常日志
            sendUserQueryLog(userId, roleCodeId, false, "QUERY_EXCEPTION: " + e.getMessage(), startTime);
            throw new RuntimeException("查询日志消息发送失败", e);
        }
    }

    /**
     * 更新用户信息
     * @param userId
     * @param user
     * @param roleCodeId
     */
    //AI进行格式优化
    @Override
    public String updateUser(Long userId, User user, Integer roleCodeId) {
        log.info("更新用户，userId：{},user：{}", userId, user);
        long startTime = System.currentTimeMillis();
        String operationResult = "SUCCESS";
        String operationDetail = "";
        Integer count = userMapper.getById(userId);
        if (count == null || count == 0) {
            return "用户不存在";
        }
        //验证邮箱格式
        if (user.getEmail() != null && !user.getEmail().matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")){
            log.info("邮箱格式错误");
            return "邮箱格式错误";
        }
        // 验证手机号格式
        if (user.getPhone() != null && !user.getPhone().matches("^1[3456789]\\d{9}$")) {
            log.info("手机号格式错误");
            return "手机号格式错误";
        }

        try {
            log.info("更新用户，当前id:{},userId：{},user：{}", UserContext.getCurrentUserId(), userId, user);

            if (roleCodeId == 2) {
                if (Objects.equals(userId, UserContext.getCurrentUserId())) {
                    operationDetail = "用户权限为使用者，且更新用户自己";
                    log.info(operationDetail);
                    userMapper.updateUser(userId, user);
                    log.info("更新用户成功，用户ID：{}", userId);
                    return "更新成功";
                } else {
                    operationResult = "FAIL";
                    operationDetail = "用户权限为使用者，更新他人，无权限";
                    log.info(operationDetail);
                    return "更新失败，用户权限为使用者，更新他人，无权限";
                }
            } else if (roleCodeId == 3) {
                if (Objects.equals(userId, UserContext.getCurrentUserId())) {
                    operationDetail = "用户权限为管理员，更新用户自己";
                    log.info(operationDetail);
                    userMapper.updateUser(userId, user);
                    log.info("更新用户成功，用户ID：{}", userId);
                    return "更新成功";
                } else {
                    List<Long> roleIds = getRoleIdsByRoleCode(roleCodeId);
                    List<Long> userIds = roleMapper.getUserIdByRoleIds(roleIds);

                    if (!userIds.contains(userId)) {
                        operationResult = "FAIL";
                        operationDetail = "用户权限为管理员，更新权限为超级管理员的人，无权限";
                        log.info(operationDetail);
                        return "更新失败，用户权限为管理员，更新权限为超级管理员的人，无权限";
                    } else {
                        operationDetail = "用户权限为管理员，更新他人";
                        log.info(operationDetail);
                        userMapper.updateUser(userId, user);
                        log.info("更新用户成功，用户ID：{}", userId);
                        return "更新成功";
                    }
                }
            } else {
                operationDetail = "用户权限为超级管理员，更新任何人";
                log.info(operationDetail);
                userMapper.updateUser(userId, user);
                log.info("更新用户成功，用户ID：{}", userId);
                return "更新成功";
            }
        } catch (Exception e) {
            operationResult = "ERROR";
            operationDetail = "更新用户异常: " + e.getMessage();
            log.error(operationDetail, e);
            throw new RuntimeException("更新用户异常", e);
        } finally {
            // 发送更新日志
            sendUserUpdateLog(
                    UserContext.getCurrentUserId(),
                    userId,
                    roleCodeId,
                    operationResult,
                    operationDetail,
                    startTime,
                    user
            );
        }
    }
    /**
     * 重置密码
     * @param userDTO
     * @param roleCodeId
     */
    //AI进行格式优化
    @GlobalTransactional
    @Override
    public String resetPassword(UserDTO userDTO, Integer roleCodeId) {
        log.info("重置密码，userId：{}", userDTO.getUserId());
        Long userId = userDTO.getUserId();
        String passWord = userDTO.getPassword();
        // 获取当前操作者ID
        Long operatorId = UserContext.getCurrentUserId();
        // 记录操作开始时间
        long startTime = System.currentTimeMillis();
        // 操作结果状态
        String operationStatus = "SUCCESS";
        // 操作详情
        String operationDetail = "";
        Integer count = userMapper.getById(userId);
        if (count == null || count == 0) {
            return "用户不存在";
        }
        try {
            if (roleCodeId == 2) {
                if (Objects.equals(userId, operatorId)) {
                    operationDetail = "用户权限为使用者，且重置用户自己密码";
                    log.info(operationDetail);
                    User user = new User();
                    user.setPassword(passWord);
                    userMapper.updateUser(userId, user);
                    log.info("重置密码成功，用户ID：{}", userId);
                    return "重置密码成功";
                } else {
                    operationStatus = "FAIL";
                    operationDetail = "用户权限为使用者，重置他人密码，无权限";
                    log.info(operationDetail);
                    return "重置密码失败，用户权限为使用者，重置他人密码，无权限";
                }
            } else if (roleCodeId == 3) {
                if (Objects.equals(userId, operatorId)) {
                    operationDetail = "用户权限为管理员，重置用户自己密码";
                    log.info(operationDetail);
                    User user = new User();
                    user.setPassword(passWord);
                    userMapper.updateUser(userId, user);
                    log.info("重置密码成功，用户ID：{}", userId);
                    return "重置密码成功";
                } else {
                    List<Long> roleIds = getRoleIdsByRoleCode(roleCodeId);
                    List<Long> userIds = roleMapper.getUserIdByRoleIds(roleIds);

                    if (!userIds.contains(userId)) {
                        operationStatus = "FAIL";
                        operationDetail = "用户权限为管理员，重置权限为超级管理员的人密码，无权限";
                        log.info(operationDetail);
                        return "重置密码失败，用户权限为管理员，重置权限为超级管理员的人密码，无权限";
                    }
                    operationDetail = "用户权限为管理员，重置用户的密码";
                    log.info(operationDetail);
                    User user = new User();
                    user.setPassword(passWord);
                    userMapper.updateUser(userId, user);
                    log.info("重置密码成功，用户ID：{}", userId);
                    return "重置密码成功";
                }
            } else {
                operationDetail = "用户权限为超级管理员，重置任何用户的密码";
                log.info(operationDetail);
                User user = new User();
                user.setPassword(passWord);
                userMapper.updateUser(userId, user);
                log.info("重置密码成功，用户ID：{}", userId);
                return "重置密码成功";
            }
        } catch (Exception e) {
            operationStatus = "ERROR";
            operationDetail = "重置密码异常: " + e.getMessage();
            log.error(operationDetail, e);
            throw new RuntimeException("重置密码异常", e);
        } finally {
            // 发送密码重置日志（同步）
            log.info("发送密码重置日志，当前用户ID：{}", UserContext.getCurrentUserId());
            sendPasswordResetLog(operatorId, userId, roleCodeId, operationStatus, operationDetail, startTime);

        }
    }

    /**
     * 异步发送密码重置日志
     */
    //AI生成
    private void sendPasswordResetLog(Long operatorId, Long targetUserId, Integer roleCode,
                                      String status, String detail, long startTime) {
        try {
            Map<String, Object> extraData = new HashMap<>();
            extraData.put("operatorId", operatorId);
            extraData.put("targetUserId", targetUserId);
            extraData.put("roleCode", roleCode);
            extraData.put("status", status);
            extraData.put("detail", detail);
            extraData.put("operationTime", System.currentTimeMillis() - startTime);
            extraData.put("clientIp", IpUtils.getIpAddr());

            UserLogMessage logMsg = new UserLogMessage(
                    operatorId,
                    "USER_RESET_PASSWORD",
                    System.currentTimeMillis(),
                    IpUtils.getIpAddr(),
                    extraData
            );

            // 使用异步发送并添加重试机制
            rocketMQTemplate.asyncSend(
                    "USER_LOG_TOPIC",
                    MessageBuilder.withPayload(logMsg)
                            .setHeader(RocketMQHeaders.TAGS, "password_reset")
                            .setHeader(RocketMQHeaders.KEYS, operatorId + "_" + targetUserId)
                            .build(),
                    new SendCallback() {
                        private int retryCount = 0;
                        private final ScheduledExecutorService retryExecutor =
                                Executors.newSingleThreadScheduledExecutor();

                        @Override
                        public void onSuccess(SendResult sendResult) {
                            log.info("密码重置日志发送成功，OperatorId: {}, TargetUserId: {}",
                                    operatorId, targetUserId);
                            retryExecutor.shutdown();
                        }

                        @Override
                        public void onException(Throwable e) {
                            if (retryCount < MAX_RETRIES) {
                                retryCount++;
                                long delay = INITIAL_RETRY_DELAY * (long) Math.pow(2, retryCount - 1);

                                log.warn("密码重置日志发送失败，准备第{}次重试（{}ms后），OperatorId: {}, TargetUserId: {}",
                                        retryCount, delay, operatorId, targetUserId);

                                retryExecutor.schedule(() -> {
                                    try {
                                        rocketMQTemplate.asyncSend(
                                                "USER_LOG_TOPIC",
                                                MessageBuilder.withPayload(logMsg)
                                                        .setHeader(RocketMQHeaders.TAGS, "password_reset")
                                                        .setHeader(RocketMQHeaders.KEYS, operatorId + "_" + targetUserId)
                                                        .build(),
                                                this
                                        );
                                    } catch (Exception ex) {
                                        log.error("密码重置日志重试发送异常，OperatorId: {}, TargetUserId: {}",
                                                operatorId, targetUserId, ex);
                                    }
                                }, delay, TimeUnit.MILLISECONDS);
                            } else {
                                log.error("密码重置日志发送失败，已达最大重试次数{}，OperatorId: {}, TargetUserId: {}",
                                        MAX_RETRIES, operatorId, targetUserId, e);
                                retryExecutor.shutdown();
                            }
                        }
                    }
            );
        } catch (Exception e) {
            log.error("密码重置日志发送异常，OperatorId: {}, TargetUserId: {}",
                    operatorId, targetUserId, e);
            throw new RuntimeException("密码重置日志发送异常", e);
        }
    }
    //AI生成
    //异步发送用户更新日志
    private void sendUserUpdateLog(Long operatorId, Long targetUserId, Integer roleCodeId,
                                   String operationResult, String operationDetail,
                                   long startTime, User updatedUser) {
        try {
            Map<String, Object> extraData = new HashMap<>();
            extraData.put("operatorRole", roleCodeId);
            extraData.put("operationTime", System.currentTimeMillis() - startTime);
            extraData.put("operationDetail", operationDetail);
            if (updatedUser != null) {
                extraData.put("updatedUser", updatedUser);
            }

            UserLogMessage logMsg = new UserLogMessage(
                    operatorId,
                    "USER_UPDATE",
                    System.currentTimeMillis(),
                    IpUtils.getIpAddr(),
                    extraData
            );

            // 异步发送
            rocketMQTemplate.asyncSend(
                    "USER_LOG_TOPIC",
                    MessageBuilder.withPayload(logMsg)
                            .setHeader(RocketMQHeaders.TAGS, "user_update")
                            .setHeader(RocketMQHeaders.KEYS, operatorId.toString())
                            .build(),
                    new SendCallback() {
                        private int retryCount = 0;

                        @Override
                        public void onSuccess(SendResult sendResult) {
                            log.debug("用户更新日志异步发送成功，MsgId: {}", sendResult.getMsgId());
                        }

                        @Override
                        public void onException(Throwable e) {
                            if (retryCount < MAX_RETRIES) {
                                retryCount++;
                                log.warn("用户更新日志发送失败，准备第{}次重试，OperatorId: {}", retryCount, operatorId);
                                try {
                                    Thread.sleep(1000 * retryCount); // 指数退避
                                    rocketMQTemplate.asyncSend(
                                            "USER_LOG_TOPIC",
                                            MessageBuilder.withPayload(logMsg)
                                                    .setHeader(RocketMQHeaders.TAGS, "user_update")
                                                    .setHeader(RocketMQHeaders.KEYS, operatorId.toString())
                                                    .build(),
                                            this
                                    );
                                } catch (Exception ex) {
                                    log.error("用户更新日志重试发送异常，OperatorId: {}", operatorId, ex);
                                }
                            } else {
                                log.error("用户更新日志发送失败，已达最大重试次数{}，OperatorId: {}", MAX_RETRIES, operatorId, e);
                                // 可以在这里添加最终失败处理逻辑，如持久化到数据库等待后续处理
                            }
                        }
                    }
            );
        } catch (Exception e) {
            log.error("用户更新日志发送异常，OperatorId: {}", operatorId, e);
            throw new RuntimeException("更新日志消息发送失败", e);
        }
    }

    //异步发送用户查询日志
    //AI生成
    private void sendUserQueryLog(Long userId, Integer roleCodeId, boolean success,
                                  String status, long startTime) {
        try {
            Map<String, Object> extraData = new HashMap<>();
            extraData.put("userId", UserContext.getCurrentUserId());
            extraData.put("QueryUserId", userId);
            extraData.put("roleCodeId", roleCodeId);
            extraData.put("status", status);
            extraData.put("queryTime", System.currentTimeMillis() - startTime);
            extraData.put("timestamp", System.currentTimeMillis());

            UserLogMessage logMsg = new UserLogMessage(
                    userId,
                    "USER_QUERY",
                    System.currentTimeMillis(),
                    IpUtils.getIpAddr(),
                    extraData
            );

            // 使用异步发送并添加重试机制
            rocketMQTemplate.asyncSend(
                    "USER_LOG_TOPIC",
                    MessageBuilder.withPayload(logMsg)
                            .setHeader(RocketMQHeaders.TAGS, success ? "user_query_success" : "user_query_fail")
                            .setHeader(RocketMQHeaders.KEYS, UserContext.getCurrentUserId().toString())
                            .build(),
                    new SendCallback() {
                        private int retryCount = 0;

                        @Override
                        public void onSuccess(SendResult sendResult) {
                            log.debug("用户查询日志异步发送成功，UserId: {}, MsgId: {}",
                                    userId, sendResult.getMsgId());
                        }

                        @Override
                        public void onException(Throwable e) {
                            if (retryCount < MAX_RETRIES) {
                                retryCount++;
                                long delay = INITIAL_RETRY_DELAY * (long) Math.pow(2, retryCount - 1);
                                log.warn("用户查询日志发送失败，准备第{}次重试，将在{}ms后重试，UserId: {}",
                                        retryCount, delay, userId, e);

                                // 使用定时线程池进行延迟重试
                                ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
                                scheduler.schedule(() -> {
                                    try {
                                        rocketMQTemplate.asyncSend(
                                                "USER_LOG_TOPIC",
                                                MessageBuilder.withPayload(logMsg)
                                                        .setHeader(RocketMQHeaders.TAGS, success ? "user_query_success" : "user_query_fail")
                                                        .setHeader(RocketMQHeaders.KEYS, UserContext.getCurrentUserId().toString())
                                                        .build(),
                                                this
                                        );
                                    } catch (Exception ex) {
                                        log.error("用户查询日志重试发送异常，UserId: {}", userId, ex);
                                    } finally {
                                        scheduler.shutdown();
                                    }
                                }, delay, TimeUnit.MILLISECONDS);
                            } else {
                                log.error("用户查询日志发送失败，已达最大重试次数{}，UserId: {}", MAX_RETRIES, userId, e);
                            }
                        }
                    }
            );
        } catch (Exception e) {
            log.error("用户查询日志发送异常，UserId: {}", userId, e);
            throw e;
        }
    }

    /**
     * 根据角色码获取角色ID集合
     * @param roleCode
     * @return
     */
    private List<Long> getRoleIdsByRoleCode(Integer roleCode) {
        if (roleCode == 1) {
            return Arrays.asList(2l, 3l); // 超级管理员对应的角色ID
        } else if (roleCode == 3) {
            return Collections.singletonList(2l); // 管理员对应的角色ID
        } else {
            return Collections.emptyList();
        }
    }
    //发送分页查询日志消息到MQ
    //AI生成
    private void sendPageQueryLog(UserQueryParam userQueryParam, Integer roleCode,
                                  int totalRecords, int currentPageSize) {
        try {
            Map<String, Object> extraData = new HashMap<>();
            extraData.put("userId", UserContext.getCurrentUserId());
            extraData.put("roleCode", roleCode);
            extraData.put("page", userQueryParam.getPage());
            extraData.put("pageSize", userQueryParam.getPageSize());
            extraData.put("totalRecords", totalRecords);
            extraData.put("currentPageRecords", currentPageSize);

            Long userId = UserContext.getCurrentUserId();

            UserLogMessage logMsg = new UserLogMessage(
                    userId,
                    "PAGE_QUERY",
                    System.currentTimeMillis(),
                    IpUtils.getIpAddr(),
                    extraData
            );

            // 使用异步发送并添加重试机制
            rocketMQTemplate.asyncSend(
                    "USER_LOG_TOPIC",
                    MessageBuilder.withPayload(logMsg)
                            .setHeader(RocketMQHeaders.TAGS, "page_query")
                            .setHeader(RocketMQHeaders.KEYS, userId.toString())
                            .build(),
                    new SendCallback() {
                        private int retryCount = 0;
                        private final ScheduledExecutorService retryExecutor =
                                Executors.newSingleThreadScheduledExecutor();

                        @Override
                        public void onSuccess(SendResult sendResult) {
                            log.info("分页查询日志发送成功，Topic: {}, MsgId: {}, QueryId: {}",
                                    "USER_LOG_TOPIC", sendResult.getMsgId(), userId.toString());
                            retryExecutor.shutdown(); // 成功时关闭线程池
                        }

                        @Override
                        public void onException(Throwable e) {
                            if (retryCount < MAX_RETRIES) {
                                retryCount++;
                                long delay = INITIAL_RETRY_DELAY * (long) Math.pow(2, retryCount - 1);

                                log.warn("分页查询日志发送失败，准备第{}次重试（{}ms后），QueryId: {}",
                                        retryCount, delay, userId);

                                retryExecutor.schedule(() -> {
                                    try {
                                        rocketMQTemplate.asyncSend(
                                                "USER_LOG_TOPIC",
                                                MessageBuilder.withPayload(logMsg)
                                                        .setHeader(RocketMQHeaders.TAGS, "page_query")
                                                        .setHeader(RocketMQHeaders.KEYS, userId.toString())
                                                        .build(),
                                                this // 传递当前回调对象
                                        );
                                    } catch (Exception ex) {
                                        log.error("分页查询日志重试发送异常，QueryId: {}", userId, ex);
                                    }
                                }, delay, TimeUnit.MILLISECONDS);
                            } else {
                                log.error("分页查询日志发送失败，已达最大重试次数{}，QueryId: {}",
                                        MAX_RETRIES, userId, e);
                                retryExecutor.shutdown(); // 最终关闭线程池
                            }
                        }
                    }
            );
        } catch (Exception e) {
            log.error("分页查询日志发送异常", e);
            throw e;
        }
    }
}
